<template>
	<!-- 接收一个id作为获取弹幕的请求，父组件可以根据close事件名关闭弹幕组件 -->
	<div class="bullet cover" ref="bullet" :class="{opa}">
		<span v-for="(item, index) in items" :key="item.id">{{item.text}}</span>
	</div>
</template>

<script>
export default{
	name: 'Bullet',
	data(){
		return{
			// 待输出的弹幕信息
			items: [],
			// 保存弹幕的信息，保存可以使用的弹幕插槽
			occupy: {},
			// 生成弹幕的id，每次加一
			num: 0
		}
	},
	props:{
		// 根据id获取实时弹幕，暂时为自定义数据
		id: {
			type: Number,
			required: true
		},
		// 父级控制弹幕透明度
		opa: {
			type: Boolean,
			default: false
		}
	},
	computed:{
		// 弹幕组件的宽度
		width(){
			return this.$refs.bullet.offsetWidth;
		},
		// 设置弹幕能容纳的行数
		rows(){
			return Math.floor(this.$refs.bullet.offsetHeight/18);
		}
	},
	watch:{
		// 检测弹幕剩余数量，为0则提交事件让父组件，关闭弹幕
		items(val){
			if(val.length == 0) this.$emit('close');
		}
	},
	methods:{
		// 插入一条弹幕，设置起始位置，过渡时间，过渡完删除弹幕
		setItem(item){
			let This = this;
			this.items.push(item);
			this.$nextTick(()=>{
				// 获取最后缓冲池里的第一条弹幕，设置插入延迟，过渡时长
				let last = this.$refs.bullet.lastChild;
				let delay = Math.floor(Math.random()*200+200);
				let speed = (Math.random()*1+this.width/40).toFixed(2);
				
				let row;
				let timer = setInterval(()=>{
					row = findNull();
					if(row){
						// 获取到了一个空位置，插入
						clearInterval(timer)
						begin(row, last, speed, delay);
						release(row);
						removeItem(delay+speed*1000+1000, item.id);
					}
				},500)
			})
			// 找到一个可以放置弹幕的位置，没有则延迟半秒再找
			function findNull(){
				let occupy = This.occupy;
				for(let i in occupy){
					if(occupy[i] == undefined){
						occupy[i] = true;
						return i;
					}
				}
			}
			// 开始过渡
			function begin(row, last, speed, delay){
				// 初始化位置
				last.style.left = This.width + last.offsetWidth + 'px';
				last.style.top = row*18 + 'px';
				last.style.transition = 'left ' + speed + 's linear';
				// 改变位置开始过渡
				setTimeout(() => {
					last.style.left = '0px';
				}, delay)
			}
			// 过渡开始后两秒释放弹幕插槽位置
			function release(row){
				This.$nextTick(()=>{
					setTimeout(()=>{
						This.occupy[row] = undefined
					}, 2000)
				})
			}
			// 过渡结束，移除单条弹幕
			function removeItem(time, id){
				setTimeout(() => {
					let index = This.items.findIndex((i)=>i.id==id)
					This.items.splice(index, 1)
				}, time)
			}
		},
		// 初始化弹幕的容器
		getBullet(){
			for(let i = 0; i < this.rows; i++){
				this.occupy[i] = undefined;
			}
		},
		// 根据id获取该视频的弹幕，暂时自定义弹幕，随机生成弹幕数据
		getData(){
			let list = ['呵呵', '呵呵呵', '。。。', '没人看的到我吧', '密探眼中的你，永远都在裸奔', '扯断你的发条', '作为你至高无上的主人，你无权拒绝我的意志', '来呀，来打我呀，你们抓不到我的，hi hi hi hi']
			let n = Math.floor(Math.random()*list.length);
			this.setItem({id: this.num++, text: list[n]});
		}
	},
	mounted() {
		this.getBullet();
	}
}
</script>

<style scoped lang="less">
.bullet{
	overflow: hidden;
	transition: opacity .5s;
	span{
		position: absolute;
		line-height: 18px;
		font-size: 14px;
		color: #fff;
		transform: translateX(-100%);
		white-space: nowrap;
		user-select: none;
	}
}
</style>
